package com.thread;

/**
 * @program: item_02
 * @description: ThreadTest
 * @author: LL
 * @create: 2021-03-10 16:04
 */
public class ThreadTest {


    public static void main(final String[] args) {
        final Person person = new Person();
        new Thread(new Input(person)).start();
        new Thread(new Output(person)).start();
        System.out.println("Hello World");
    }
}

class Person {
    String name;
    String gender;
    boolean flag = false;//标记，默认不输出
}

class Input implements Runnable {

    private Person p;
    private int n = 0;

    public Input(final Person p) {
        this.p = p;
    }

    @Override
    public void run() {
        while (true) {
            synchronized (this.p) {//两个Runnable用同一个Person初始化，可保证p是同一个且唯一
                if (this.p.flag) {
                    try {
                        this.p.wait();
                    } catch (final InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                    }
                }
                if (this.n == 0) {
                    this.p.name = "Jason";
                    this.p.gender = "男";
                } else {
                    this.p.name = "Lily";
                    this.p.gender = "女";
                }
                this.n = (this.n + 1) % 2;
                this.p.flag = true;//修改标志位
                this.p.notify();//唤醒另一个
            }
        }
    }
}

class Output implements Runnable {
    private Person p;

    public Output(final Person p) {
        this.p = p;
    }

    @Override
    public void run() {
        while (true) {
            synchronized (this.p) {
                //仍然是判断标志位和上面的线程轮流等待，唤醒
                if (!this.p.flag) {
                    try {
                        this.p.wait();
                    } catch (final InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                    }
                }
                System.out.println(this.p.name + "..." + this.p.gender);
                //改变标志位和唤醒另一个
                this.p.flag = true;//让自己回来等待
                this.p.notify();//同一个锁，唤醒锁上的另一个
            }
        }
    }
}
